package br.edu.fanor.managedbeans;

import br.edu.fanor.entidades.Filme;
import br.edu.fanor.managedbeans.util.JsfUtil;
import br.edu.fanor.managedbeans.util.Paginacao;
import br.edu.fanor.sessionbeans.FilmeBean;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import javax.annotation.security.RolesAllowed;
import javax.ejb.EJB;
import javax.enterprise.context.SessionScoped;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.convert.Converter;
import javax.faces.convert.FacesConverter;
import javax.faces.model.DataModel;
import javax.faces.model.ListDataModel;
import javax.faces.model.SelectItem;
import javax.inject.Named;

@Named("filmeController")
@SessionScoped
public class FilmeMB implements Serializable {

    private Filme filme;
    private DataModel itens = null;
    @EJB
    private br.edu.fanor.sessionbeans.FilmeBean FilmeBean;
    private Paginacao paginacao;
    private int IndiceItemSelecionado;
    private List<Filme> filmes = new ArrayList<>();

    public FilmeMB() {
    }

    public List<Filme> getFilmes() {
        return filmes;
    }

    public void setFilmes(List<Filme> filmes) {
        this.filmes = filmes;
    }
  
    public void AdionarFilme() {
        filmes.add(filme);
    }
    
    public Filme getSelecionado() {
        if (filme == null) {
            filme = new Filme();
            IndiceItemSelecionado = -1;
        }
        return filme;
    }
    
    private FilmeBean getFachada() {
        return FilmeBean;
    }

    public Paginacao getPaginacao() {
        if (paginacao == null) {
            paginacao = new Paginacao(10) {

                @Override
                public int getContagemItens() {
                    return getFachada().count();
                }

                @Override
                public DataModel criarPaginaModeloDados() {
                    return new ListDataModel(getFachada().buscarColecao(new int[]{getPaginaPrimeiroItem(), getPaginaPrimeiroItem() + getTamanhoPagina()}));
                }
            };
        }
        return paginacao;
    }

    public String prepararLista() {
        readicionarModelo();
        return "ListarFilme";
    }

    public String prepararVizualizacao() {
        filme = (Filme) getItens().getRowData();
        IndiceItemSelecionado = paginacao.getPaginaPrimeiroItem() + getItens().getRowIndex();
        return "ListarFilme";
    }

    public String prepararParaAdicionar() {
        filme = new Filme();
        IndiceItemSelecionado = -1;
        return "CadastrarFilme";
    }

    public String adicionar() {
        try {
            getFachada().adicionar(filme);
            JsfUtil.addMensagemSucesso("Filme Cadastrado");
            return prepararParaAdicionar();
        } catch (Exception e) {
            JsfUtil.addMensagemErro(e, "Ocorreu um erro durante a operação de persistencia");
            return null;
        }
    }

    public String prepararEdicao() {
        filme = (Filme) getItens().getRowData();
        IndiceItemSelecionado = paginacao.getPaginaPrimeiroItem() + getItens().getRowIndex();
        return "EditarFilme";
    }

    public String atualizar() {
        try {
            getFachada().editar(filme);
            JsfUtil.addMensagemSucesso("Filme Atualizado");
            return "ListarFilme";
        } catch (Exception e) {
            JsfUtil.addMensagemErro(e, "Ocorreu um erro durante a operação de persistencia");
            return null;
        }
    }
    @RolesAllowed({"ADMIN"})
    public String remover() {
        filme = (Filme) getItens().getRowData();
        IndiceItemSelecionado = paginacao.getPaginaPrimeiroItem() + getItens().getRowIndex();
        executarRemocao();
        readicionarPaginacao();
        readicionarModelo();
        return "ListarFilme";
    }

    public String removerEVizualizar() {
        executarRemocao();
        readicionarModelo();
        atualizarFilmeItem();
        if (IndiceItemSelecionado >= 0) {
            return "ListarFilme";
        } else {
            // all itens were removed - go back to list
            readicionarModelo();
            return "ListarFilme";
        }
    }

    private void executarRemocao() {
        try {
            getFachada().remover(filme);
            JsfUtil.addMensagemSucesso("Filme Removido");
        } catch (Exception e) {
            JsfUtil.addMensagemErro(e, "Ocorreu um erro durante a operação de persistencia");
        }
    }

    private void atualizarFilmeItem() {
        int count = getFachada().count();
        if (IndiceItemSelecionado >= count) {
            // selected index cannot be bigger than number of itens:
            IndiceItemSelecionado = count - 1;
            // go to anterior page if last page disappeared:
            if (paginacao.getPaginaPrimeiroItem() >= count) {
                paginacao.paginaAnterior();
            }
        }
        if (IndiceItemSelecionado >= 0) {
            filme = getFachada().buscarColecao(new int[]{IndiceItemSelecionado, IndiceItemSelecionado + 1}).get(0);
        }
    }

    public DataModel getItens() {
        if (itens == null) {
            itens = getPaginacao().criarPaginaModeloDados();
        }
        return itens;
    }

    private void readicionarModelo() {
        itens = null;
    }

    private void readicionarPaginacao() {
        paginacao = null;
    }

    public String proximo() {
        getPaginacao().proximaPagina();
        readicionarModelo();
        return "ListarFilme";
    }

    public String anterior() {
        getPaginacao().paginaAnterior();
        readicionarModelo();
        return "ListarFilme";
    }

    public SelectItem[] getSelecioneMuitos() {
        return JsfUtil.getItensSelecionados(FilmeBean.buscarTodos(), false);
    }

    public SelectItem[] getSelecioneUm() {
        return JsfUtil.getItensSelecionados(FilmeBean.buscarTodos(), true);
    }

    public Filme getFilme(java.lang.Long id) {
        return FilmeBean.buscar(id);
    }
    
    public Filme getFilme(java.lang.String nome) {
        return FilmeBean.buscar(nome);
    }

    @FacesConverter(forClass = Filme.class)
    public static class FilmeMBConverter implements Converter {

        @Override
        public Object getAsObject(FacesContext facesContext, UIComponent component, String value) {
            if (value == null || value.length() == 0) {
                return null;
            }
            FilmeMB controller = (FilmeMB) facesContext.getApplication().getELResolver().
                    getValue(facesContext.getELContext(), null, "filmeController");
            return controller.getFilme(getKey(value));
        }

        java.lang.Long getKey(String value) {
            java.lang.Long key;
            key = Long.valueOf(value);
            return key;
        }

        String getStringKey(java.lang.Long value) {
            StringBuilder sb = new StringBuilder();
            sb.append(value);
            return sb.toString();
        }

        @Override
        public String getAsString(FacesContext facesContext, UIComponent component, Object object) {
            if (object == null) {
                return null;
            }
            if (object instanceof Filme) {
                Filme o = (Filme) object;
                return getStringKey(o.getId());
            } else {
                throw new IllegalArgumentException("object " + object + " is of type " + object.getClass().getName() + "; expected type: " + Filme.class.getName());
            }
        }

    }

}

